package pl.com.kyhu.dietex3000.GUI.dialogs;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.wb.swt.SWTResourceManager;

import pl.com.kyhu.dietex3000.GUI.components.IngredientTree;
import pl.com.kyhu.dietex3000.database.beans.Ingredient;
import pl.com.kyhu.dietex3000.database.beans.Meal;
import pl.com.kyhu.dietex3000.database.beans.MealCategory;
import pl.com.kyhu.dietex3000.database.beans.Proportion;
import pl.com.kyhu.dietex3000.database.management.DataManagement;
import pl.com.kyhu.dietex3000.utils.Constants;

public class NewMealDialog extends Dialog {

	protected Object result;
	protected Shell shell;

	private Button addButton;
	private Button deleteButton, cancelButton, saveButton;

	private Text proportionText;
	private Text nameText;
	private Text recipeText;

	private CCombo categoryCombo;

	private IngredientTree ingredientTree;
	private Table mealTable;

	private Map<TreeItem, Ingredient> availableIngredients;
	private Map<TableItem, Proportion> mealProportion = new HashMap<TableItem, Proportion>();
	private CCombo subCategoryCombo;

	public NewMealDialog(Shell parent, int style) {
		super(parent, style);
		setText("Nowa potrawa");
	}

	public Object open() {
		createContents();
		shell.open();
		shell.layout();
		Display display = getParent().getDisplay();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
		return result;
	}

	private void createContents() {
		shell = new Shell(getParent(), SWT.SHELL_TRIM | SWT.BORDER);
		shell.setSize(521, 516);
		shell.setText(getText());

		ingredientTree = new IngredientTree(shell, SWT.NONE);
		ingredientTree.setBounds(10, 177, 294, 267);
		availableIngredients = ingredientTree.getIngredients();

		addButton = new Button(shell, SWT.NONE);
		addButton.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				if (proportionText.getText() != "" && ingredientTree.getSelection() != null
						&& availableIngredients.containsKey(ingredientTree.getSelection())) {
					addProportion();
				}
			}
		});
		addButton.setFont(SWTResourceManager.getFont("Microsoft Sans Serif", 8, SWT.NORMAL));

		addButton.setBounds(148, 450, 156, 24);
		addButton.setText("Dodaj >>");

		proportionText = new Text(shell, SWT.BORDER);
		proportionText.setBounds(10, 450, 106, 24);

		Label gramLabel = new Label(shell, SWT.NONE);
		gramLabel.setFont(SWTResourceManager.getFont("Microsoft Sans Serif", 11, SWT.NORMAL));
		gramLabel.setBounds(122, 452, 20, 24);
		gramLabel.setText("g");

		Label separator = new Label(shell, SWT.SEPARATOR | SWT.VERTICAL);
		separator.setBounds(310, 177, 2, 299);

		mealTable = new Table(shell, SWT.BORDER | SWT.FULL_SELECTION);
		mealTable.setBounds(318, 177, 185, 239);
		mealTable.setHeaderVisible(true);
		mealTable.setLinesVisible(true);

		TableColumn ingredientColumn = new TableColumn(mealTable, SWT.NONE);
		ingredientColumn.setWidth(113);
		ingredientColumn.setText("Sk\u0142adniki");

		TableColumn amountColumn = new TableColumn(mealTable, SWT.NONE);
		amountColumn.setWidth(67);
		amountColumn.setText("Waga");

		deleteButton = new Button(shell, SWT.NONE);
		deleteButton.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				if (mealTable.getSelection() != null && mealTable.getSelection().length > 0) {
					deleteProportion();
				}
			}

		});
		deleteButton.setBounds(316, 423, 68, 23);
		deleteButton.setText(" << Usu\u0144");

		cancelButton = new Button(shell, SWT.NONE);
		cancelButton.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				shell.close();
			}
		});
		cancelButton.setBounds(316, 453, 68, 23);
		cancelButton.setText("Anuluj");

		saveButton = new Button(shell, SWT.NONE);
		saveButton.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				if (!mealProportion.isEmpty() && recipeText.getText() != "" && nameText.getText() != ""
						&& !categoryCombo.getText().equals(Constants.categoryText)) {
					createMeal();
				}
			}

		});
		saveButton.setBounds(397, 423, 106, 53);
		saveButton.setText("Zapisz");

		nameText = new Text(shell, SWT.BORDER);
		nameText.setText("Nazwa");
		nameText.setBounds(10, 10, 493, 19);

		recipeText = new Text(shell, SWT.BORDER | SWT.MULTI);
		recipeText.setText("Przepis..");
		recipeText.setBounds(10, 35, 493, 86);

		categoryCombo = new CCombo(shell, SWT.BORDER | SWT.READ_ONLY);
		categoryCombo.setBounds(10, 127, 493, 21);
		categoryCombo.removeAll();
		categoryCombo.setText(Constants.categoryText);
		categoryCombo.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
				fillSubCategories();
			}

			@Override
			public void widgetSelected(SelectionEvent e) {
				fillSubCategories();
			}
		});

		subCategoryCombo = new CCombo(shell, SWT.BORDER | SWT.READ_ONLY);
		subCategoryCombo.setText("Podkategoria");
		subCategoryCombo.setBounds(10, 150, 493, 21);
		fillCategories();
		fillSubCategories();
		categoryCombo.setText(Constants.categoryText);

	}

	private void addProportion() {

		Ingredient ingredient = availableIngredients.get(ingredientTree.getSelection());
		Integer amount = Integer.parseInt(proportionText.getText());

		Proportion proportion = new Proportion();
		proportion.setAmount(amount);
		proportion.setIngredient(ingredient);

		TableItem tableItem = new TableItem(mealTable, SWT.NONE);
		tableItem.setText(0, ingredient.getName());
		tableItem.setText(1, amount.toString() + "g");

		mealProportion.put(tableItem, proportion);

		proportionText.setText("");

	}

	private void normalizeProportion() {
		Integer sum = 0;
		for (Proportion proportion : mealProportion.values()) {
			sum += proportion.getAmount();
		}

		Float coef = (float) (100.0 / sum);

		for (Proportion proportion : mealProportion.values()) {
			proportion.setAmount(Math.round((proportion.getAmount() * coef)));
		}

	}

	private void deleteProportion() {
		mealProportion.remove(mealTable.getSelection()[0]);
		mealTable.remove(mealTable.getSelectionIndex());
	}

	private void createMeal() {
		Meal meal = new Meal();
		normalizeProportion();
		for (Proportion proportion : mealProportion.values()) {
			meal.addProportion(proportion);
		}
		meal.setRecipe(recipeText.getText());
		meal.setName(nameText.getText());

		MealCategory category;
		if (subCategoryCombo.isEnabled()) category = DataManagement.getMealCategory(subCategoryCombo.getText());
		else
			category = DataManagement.getMealCategory(categoryCombo.getText());

		meal.setCategory(category);
		DataManagement.save(meal);

		clearCompontents();
	}

	private void clearCompontents() {
		recipeText.setText("Recipe..");
		nameText.setText("Name");
		proportionText.setText("");
		mealTable.removeAll();
		mealProportion = new HashMap<TableItem, Proportion>();
	}

	private void fillCategories() {
		List<MealCategory> categories = DataManagement.getMealSubCategories(Constants.mealCategoryNode);
		categoryCombo.setText(categories.get(0).getName());
		categoryCombo.setFont(SWTResourceManager.getFont("Microsoft Sans Serif", 8, SWT.BOLD));
		for (MealCategory mc : categories) {
			categoryCombo.add(mc.getName());
		}
	}

	private void fillSubCategories() {
		MealCategory mainCategory = DataManagement.getMealCategory(categoryCombo.getText());
		List<MealCategory> subCategories = DataManagement.getMealSubCategories(mainCategory);
		subCategoryCombo.removeAll();
		if (subCategories.isEmpty()) subCategoryCombo.setEnabled(false);
		else {
			subCategoryCombo.setEnabled(true);
			subCategoryCombo.setText(subCategories.get(0).getName());
			for (MealCategory mc : subCategories) {
				subCategoryCombo.add(mc.getName());
			}
		}
	}
}
